home *** CD-ROM | disk | FTP | other *** search
/ 8bitfiles.net/archives / archives.tar / archives / genie-commodore-file-library / Information / COMAL.DRAW.ARC / DRAWING IN COMAL
Encoding:
Text File  |  2019-04-13  |  17.0 KB  |  519 lines

  1. *********************************************************************
  2. This article is being presented through the *StarBoard* Journal of
  3. the FlagShip/StarShip, SIGS (Special Interest Groups) on the
  4. Delphi and GEnie telecommunications networks.  Permission is
  5. hereby granted to non-profit organizations only to reprint this
  6. article or pass it along electronically as long as proper credit
  7. is given to both the author and the *StarBoard* Journal.
  8. *********************************************************************
  9.  
  10.                      DRAWING IN COMAL 0.14
  11.  
  12.                        by Valerie Kramer
  13.  
  14. *********************************************************************
  15. [ED. NOTE: This article is perfect for those who lack documentation for
  16. COMAL.  It contains a complete program to draw a picture.  This article
  17. is reprinted by permission from:
  18.     COMAL TODAY
  19.     6041 Monona Drive
  20.     Madison, WI 53716
  21. and is copyrighted 1985 by Valerie Kramer.]
  22. *********************************************************************
  23.  
  24. A friend of mine got me started some time back when he asked for
  25. help in programming a Keno game in COMAL. Thanks to that project I
  26. got past the learning curve of COMAL and realized what a treasure
  27. I had in the language. Well, that same friend has been at it
  28. again. I suggested he try a simple project by himself: a COMAL
  29. program to draw a "Kilroy" picture. You know, a brick wall with a
  30. simple face peering over the top. He tried, but I found that he
  31. really didn't have the first idea where to start. So, for those of
  32. you in the same boat, here is how you can draw Kilroy or anything
  33. else. I have no artistic talent worth mentioning, so I will leave
  34. details of composition to your imagination. I want to show what
  35. the various COMAL graphics statements are, how to use them, and
  36. how to produce the simple geometric patterns from which many
  37. pictures are made.
  38.  
  39. The COMAL graphic commands are shown in the list below, grouped by
  40. function. We will see many of them in this article. You may wish
  41. to look up those we don't use. Most of them are pretty simple once
  42. you have a general idea of what is going on, and I hope you have
  43. that idea by the end of the article.
  44.  
  45.     SETGRAPHIC   SETTEXT
  46.     FULLSCREEN   SPLITSCREEN
  47.     BACKGROUND   BORDER       PENCOLOR
  48.     HIDETURTLE   SHOWTURTLE   TURTLESIZE
  49.     PENDOWN      PENUP
  50.     DRAWTO       MOVETO       SETXY
  51.     LEFT         RIGHT        SETHEADING
  52.     BACK         FORWARD
  53.     HOME
  54.     CLEAR
  55.     FRAME
  56.     PLOT         FILL
  57.     PLOTTEXT
  58.  
  59. The first thing you need to do is to get into COMAL. From COMAL
  60. you must enter graphics mode:
  61.  
  62.         SETGRAPHIC 0
  63.  
  64. That puts you in the high-res graphics mode. (There is also a
  65. multi-color mode, SETGRAPHIC 1, which works pretty much the same
  66. as high-res. Let's save it for another time.)  At this point, you
  67. should see a blank screen with a triangular-shaped turtle in the
  68. center and a couple of lines across the top of the screen in a
  69. different color. The large area is your graphic screen. The small
  70. area at the top is a text area where you can give commands. Let's
  71. try a couple of commands just for fun. Press the RETURN key after
  72. each command.
  73.  
  74.         FORWARD 50
  75.         RIGHT 90
  76.         FORWARD 50
  77.         RIGHT 90
  78.         FORWARD 50
  79.         RIGHT 90
  80.         FORWARD 50
  81.  
  82. Did your turtle draw a box?  You can clear your screen and start
  83. over with the command CLEAR. You can return the turtle to the
  84. starting position without clearing the screen by using the HOME
  85. command. Try them now.
  86.  
  87.         HOME
  88.         CLEAR
  89.  
  90. We can control the turtle with the HIDETURTLE, SHOWTURTLE, and
  91. TURTLESIZE commands. Try these:
  92.  
  93.         HIDETURTLE
  94.         SHOWTURTLE
  95.         TURTLESIZE 0
  96.         TURTLESIZE 5
  97.         TURTLESIZE 10
  98.  
  99. Next, let's get a good map of the graphic screen in our mind.
  100. There are 64,000 distinct points on the screen. They are arranged
  101. in a rectangle 200 points high by 320 wide. Each point is labeled
  102. by two numbers. The first number tells how far the point is from
  103. the left edge, and the second tells how far from the bottom of the
  104. screen. Thus the lower left point is 0,0 because it is at the left
  105. edge and on the bottom. The top right point is 319,199. The center
  106. of the screen is called the "home" position of the turtle. It is
  107. located at point 160,99.
  108.  
  109.     y  0,199....160,199....319,199
  110.     y  ...........................
  111.     y  ...........................
  112.     y  0,99.....160,99......319,99
  113.     y  ...........................
  114.     y  ...........................
  115.     y  0,0......160,0........319,0
  116.  
  117.        xxxxxxxxxxxxxxxxxxxxxxxxxxx
  118.  
  119. Now that we know how our points are numbered, we can turn on any
  120. point we want using the PLOT command. PLOT x,y turns on the single
  121. point located at the specified x,y position. Let's try some and
  122. get a feel for our screen.
  123.  
  124.         PLOT 160,200
  125.         PLOT 140,99
  126.         PLOT 140,95
  127.         PLOT 10,10
  128.         PLOT 315,195
  129.         PLOT 5,195
  130.         PLOT 317,5
  131.  
  132. Continue playing until you have a good feel for the screen
  133. coordinate system.
  134.  
  135. The next geometric figure is the straight line. From geometry we
  136. know that two points determine a line. We need a starting and an
  137. ending point. To draw a line on our screen, we first move to the
  138. starting point of our line then draw a line to the ending point.
  139.  
  140. There are a couple ways of doing this. Here are some examples:
  141.  
  142.      A           SETXY 23,99
  143.         FORWARD 51
  144.  
  145.         MOVETO 25,99
  146.         DRAWTO 25,150
  147.  
  148.     Or
  149.         SETXY 235,185
  150.         FORWARD 36
  151.  
  152.         MOVETO 235,180
  153.         DRAWTO 270,180
  154.  
  155. How about lines at angles? Sure!
  156.  
  157.         SETXY 170,150
  158.         SETHEADING 135
  159.         FORWARD 75
  160.  
  161.         MOVETO 160,150
  162.         DRAWTO 210,100
  163.  
  164. Try some of your own. When you are done, clear the screen with the
  165. CLEAR command. Note that the SETHEADING command turns the turtle
  166. to the specified angle where zero degrees is straight up, 90
  167. degrees is right, etc. Some projects will be more easily drawn
  168. with MOVETO and DRAWTO while others will do better with SETXY,
  169. SETHEADING, and FORWARD type commands.
  170.  
  171. Now let's try for some polygons starting with a triangle. We move
  172. to the first point, draw to the second, draw to the third, then
  173. draw to the first again.
  174.  
  175.         MOVETO 140,99
  176.  
  177.         DRAWTO 160,129
  178.         DRAWTO 180,99
  179.         DRAWTO 140,99
  180.  
  181. I'll leave other straight-lined figures for you to work out on
  182. your own. You know how to put any kind of a straight line on the
  183. screen at any place you wish, so you should really have no
  184. problems.
  185.  
  186. Since we are going to get into more complicated figures, it's time
  187. to change our method of operation. Instead of typing in each
  188. command and watching it execute, we will write a program
  189. containing the commands. When it is just the way we want it, we
  190. will RUN it and have our picture drawn for us. This has several
  191. advantages. We can save our program for repeated use. We can make
  192. use of loops and other program constructs that are not available
  193. as direct commands. When we make a goof, we need only correct the
  194. program. We don't have to type all the other commands over, too.
  195.  
  196. Let's get out of graphics mode. You can give the command SETTEXT
  197. or just hit the F1 key. If you type SETGRAPHIC without a number,
  198. or hit the F3 key you will be back in split screen graphics mode
  199. and can review your picture. F5 puts you in fullscreen graphics
  200. mode. You can also change modes with the SPLITSCREEN and
  201. FULLSCREEN commands, but the function keys are simpler to use. Try
  202. playing with the them now, then return to text mode (F1).
  203.  
  204. Since we start our program from text mode, the first thing it
  205. needs to do is to enter graphics mode. We will not be giving
  206. commands in graphics mode (our program does that for us), so let's
  207. use the fullscreen graphics. Finally let's hide the turtle so we
  208. can see only the points and lines we've drawn. Our program will
  209. begin like this:
  210.  
  211.     10  // Comment to identify our program.
  212.     20  setgraphic 0
  213.     30  fullscreen
  214.     40  hideturtle
  215.  
  216. I haven't said anything about colors yet, but let's set our
  217. background and border colors. We may need to look up the color
  218. numbers in the Commodore Programmer's Reference Guide. COMAL uses
  219. the same color numbers used by BASIC. Black is 0, White is 1, Red
  220. is 2, Green is 5, Blue is 6, etc.
  221.  
  222.     50 background 1
  223.     60 border 5
  224.     70 clear
  225.  
  226. The CLEAR command will erase the graphics screen and set it all to
  227. the color we last specified with the BACKGROUND command. We can
  228. also set the color of the lines we want drawn. We do this with the
  229. PENCOLOR statement.
  230.  
  231.     80 pencolor 6
  232.  
  233. We're all set now, but what shall we do? Let's draw the square we
  234. drew earlier in the direct command mode.
  235.  
  236.     90  forward 50
  237.     100 right 90
  238.     110 forward 50
  239.     120 right 90
  240.     130 forward 50
  241.     140 right 90
  242.     150 forward 50
  243.  
  244. Now run it. Because we are in program mode, we can make use of
  245. loop and conditional structures. FOR-ENDFOR loops are particularly
  246. useful for polygons. Let's improve the square program with a FOR
  247. loop.
  248.  
  249.     0010  // improved square program
  250.     0020 setgraphic 0
  251.     0030 fullscreen
  252.     0040 hideturtle
  253.     0050 background 1
  254.     0060 border 5
  255.     0070 clear
  256.     0080 pencolor 6
  257.     0090 for side = 1 to 4
  258.     0100  forward 50
  259.     0110  right 90
  260.     0120 endfor side
  261.  
  262. With a simple change, we can make this program print any polygon.
  263. Add line 15 and replace lines 90 thru 120 with this:
  264.  
  265.     0015 input "how many sides? ":number
  266.  
  267.     0090 //
  268.     0100 for sides= 1 to number do
  269.     0110  forward 10
  270.     0120  right 360/number
  271.     0130 endfor sides
  272.  
  273. Try some programs of your own. You might also want to use the LEFT
  274. and BACK commands. They work like RIGHT and FORWARD but go in the
  275. other direction.
  276.  
  277. In order to draw curved lines, we cheat. The COMAL statements
  278. necessary have already been written for us and are found in the
  279. Library of Functions and Procedures book/disk set. It includes
  280. procedures that will draw circles and arcs for us. All we have to
  281. do is merge the procedures from the library disk into our program
  282. and call them as needed. The book explains how to call each
  283. routine.
  284.  
  285. To merge a library procedure or function with your program you
  286. write your program making sure that you do not use any line
  287. numbers greater than 8999. The library routines start at 9000.
  288. When you are ready, you ENTER the library routine. This will merge
  289. it from disk and put it at the end of your program. Remember that
  290. ENTER only works with SEQ files (as created by LISTing a program
  291. section to disk)!
  292.  
  293. The library disk is set up so ENTER will work. After the library
  294. routine is entered, renumber your program to make room for any
  295. additional routines you may want to merge:
  296.  
  297.         RENUM
  298.  
  299. If you forget to renumber, the next routine you ENTER will overlay
  300. all or part of the first one and you will have a real mess.
  301.  
  302. It's time to start drawing Kilroy. Kilroy consists of a wall of
  303. bricks (let's keep it simple with only three rows of bricks) with
  304. Kilroy's head peeking over the wall. For extra credit, you
  305. ambitious ones can add Kilroy's fingers and nose or extend the
  306. picture in other ways. For now we need to draw two objects - a
  307. brick wall, and a head. The brick wall can be seen in several
  308. ways:
  309.  
  310.      1. A lot of distinct lines
  311.      2. A box with two horizontal lines and
  312.          a bunch of vertical ones
  313.      3. three rows of bricks.
  314.  
  315. The third alternative is probably the best because it is the most
  316. general description. We can easily draw a brick. It's just a
  317. variation of our square program. Next we can learn to draw a row
  318. of bricks, and finally we can draw three such rows. By abstracting
  319. the program this way, we will later be able to change the size of
  320. the brick, the number of bricks in a row, the number of rows, etc.
  321. With the other two approaches these changes would be very
  322. difficult.
  323.  
  324. In fact, to keep things very modular, we will put each of our
  325. abstractions into its own procedure. Let's write the BRICK PROC:
  326.  
  327.     310 proc brick(high,wide) closed
  328.     320  for side:=1 to 2 do
  329.     330   forward high
  330.     340   right 90
  331.     350   forward wide
  332.     360   right 90
  333.     370  endfor side
  334.     380  //
  335.     390  left 90
  336.     400  back wide
  337.     410  right 90
  338.     420 endproc brick
  339.  
  340. Notice that we had to use separate FORWARD commands for the two
  341. adjacent sides since they may not be the same length. The LEFT,
  342. BACK, RIGHT statements at the end of the proc move the turtle to
  343. the right end of the brick in position to draw an adjacent brick.
  344. This will make our procedure to draw a row of bricks very simple:
  345.  
  346.     440 proc row'of'bricks(count,high,wide) cl
  347.         osed // wrap line
  348.     450  for i:=1 to count do
  349.     460   brick(high,wide)
  350.     470  endfor i
  351.     480 endproc row'of'bricks
  352.  
  353. There is only one small problem. Succeeding rows of bricks
  354. alternate a short and a long brick at the start of the row. We can
  355. make a second proc for the other row of bricks:
  356.  
  357.     500 proc other'row'of'bricks(count,high,wi
  358.         de) closed // wrap line
  359.     510  short:=int(wide/2)
  360.     520  brick(high,short)
  361.     530  //
  362.     540  for i:=1 to count-1 do
  363.     550   brick(high,wide)
  364.     560  endfor i
  365.     570  //
  366.     580  short:=wide-short
  367.     590  brick(high,short)
  368.     600 endproc other'row'of'bricks
  369.  
  370. We had to be careful in our computations because we don't want to
  371. end up with one row of bricks shorter than another. We are now
  372. ready for our wall procedure:
  373.  
  374.     620 proc brick'wall(x,y,rows,count,high,wi
  375.          de) closed // wrap line
  376.     630  moveto x,y
  377.     640  case (rows mod 2) of
  378.     650  when 0
  379.     660   for i:=1 to rows/2 do
  380.     670    row'of'bricks(count,high,wide)
  381.     680    moveto x,y-(2*i*high)
  382.     690    other'row'of'bricks(count,high,wide)
  383.     700    moveto x,y-((2*i+1)*high)
  384.     710   endfor i
  385.     720  when 1
  386.     730   row'of'bricks(count,high,wide)
  387.     740   moveto x,y-high
  388.     750   for i:=1 to (rows-1)/2 do
  389.     760    other'row'of'bricks(count,high,wide)
  390.     770    moveto x,y-(2*i*high)
  391.     780    row'of'bricks(count,high,wide)
  392.     790    moveto x,y-((2*i+1)*high)
  393.     800   endfor i
  394.     810  endcase
  395.     820 endproc brick'wall
  396.  
  397. Again, we had to be careful because we might call for either an
  398. even or odd number of bricks. Note that we must also be sure to
  399. set our position before drawing each row of bricks.
  400.  
  401. Our main program is very much like it used to be:
  402.  
  403.     100 // for comal 0.14 - kilroy was here
  404.     110 // delete "0:c14.kilroy"
  405.     120 // save   "0:c14.kilroy"
  406.     130 setgraphic 0
  407.     140 fullscreen
  408.     150 hideturtle
  409.     160 background 1
  410.     170 border 5
  411.     180 clear
  412.     190 pencolor 0
  413.     200 brick'wall(20,80,3,10,10,25)
  414.     210 arc(160,90,40,0,180) // head
  415.  
  416. Finally we start tinkering and add the bells and whistles. We add
  417. eyes and a nose as well as a title for the picture. Here is the
  418. final version as far as I have taken it. Now it's your turn to
  419. experiment both with this picture and others of your own creation.
  420. Good luck and have fun!
  421.  
  422.     0100 // for comal 0.14 - kilroy was here
  423.     0110 // delete "0:kilroy"
  424.     0120 //   save "0:kilroy"
  425.     0130 setgraphic 0
  426.     0140 fullscreen
  427.     0150 hideturtle
  428.     0160 background 1
  429.     0170 border 5
  430.     0180 clear
  431.     0190 pencolor 0
  432.     0200 brick'wall(20,80,3,10,10,25)
  433.     0210 arc(160,90,40,0,180) // head
  434.     0220 pendown
  435.     0230 moveto 150,115
  436.     0240 brick(4,4) // eye
  437.     0250 moveto 170,115
  438.     0260 brick(4,4) // eye
  439.     0270 moveto 160,100
  440.     0280 brick(6,4) // mouth
  441.     0290 plottext 100,10,"kilroy was here"
  442.     0300 //
  443.     0310 proc brick(high,wide) closed
  444.     0320  for side:=1 to 2 do
  445.     0330   forward high
  446.     0340   right 90
  447.     0350   forward wide
  448.     0360   right 90
  449.     0370  endfor side
  450.     0380  //
  451.     0390  left 90
  452.     0400  back wide
  453.     0410  right 90
  454.     0420 endproc brick
  455.     0430 //
  456.     0440 proc row'of'bricks(count,high,wide) c
  457.          losed // wrap line
  458.     0450  for i:=1 to count do
  459.     0460   brick(high,wide)
  460.     0470  endfor i
  461.     0480 endproc row'of'bricks
  462.     0490 //
  463.     0500 proc other'row'of'bricks(count,high,w
  464.          ide) closed // wrap line
  465.     0510  short:=int(wide/2)
  466.     0520  brick(high,short)
  467.     0530  //
  468.     0540  for i:=1 to count-1 do
  469.     0550   brick(high,wide)
  470.     0560  endfor i
  471.     0570  //
  472.     0580  short:=wide-short
  473.     0590  brick(high,short)
  474.     0600 endproc other'row'of'bricks
  475.     0610 //
  476.     0620 proc brick'wall(x,y,rows,count,high,w
  477.          ide) closed // wrap line
  478.     0630  moveto x,y
  479.     0640  case (rows mod 2) of
  480.     0650  when 0
  481.     0660   for i:=1 to rows/2 do
  482.     0670    row'of'bricks(count,high,wide)
  483.     0680    moveto x,y-(2*i*high)
  484.     0690    other'row'of'bricks(count,high,wid
  485.             e) // wrap line
  486.     0700    moveto x,y-((2*i+1)*high)
  487.     0710   endfor i
  488.     0720  when 1
  489.     0730   row'of'bricks(count,high,wide)
  490.     0740   moveto x,y-high
  491.     0750   for i:=1 to (rows-1)/2 do
  492.     0760    other'row'of'bricks(count,high,wid
  493.             e) // wrap line
  494.     0770    moveto x,y-(2*i*high)
  495.     0780    row'of'bricks(count,high,wide)
  496.     0790    moveto x,y-((2*i+1)*high)
  497.     0800   endfor i
  498.     0810  endcase
  499.     0820 endproc brick'wall
  500.     0830 //
  501.     0840 proc arc(x,y,r,sa,ca) closed
  502.     0850  moveto x,y
  503.     0860  setheading 90-sa
  504.     0870  penup
  505.     0880  forward r
  506.     0890  left 90
  507.     0900  pendown
  508.     0910  arcl(r,ca)
  509.     0920  penup
  510.     0930 endproc arc
  511.     0940 //
  512.     0950 proc arcl(r,ca) closed
  513.     0960  for i:=1 to ca/10 do
  514.     0970   left 5
  515.     0980   forward r*3.14159/18
  516.     0990   left 5
  517.     1000  endfor i
  518.     1010 endproc arcl
  519.